/**
* @file op_model_manager.h
*
* Copyright (C) Huawei Technologies Co., Ltd. 2019-2020. All Rights Reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef ACL_OP_EXEC_OP_MODEL_MANAGER_H_
#define ACL_OP_EXEC_OP_MODEL_MANAGER_H_

#include "acl/acl.h"

#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <memory>
#include <mutex>

#include "graph/ge_attr_value.h"
#include "mmpa/mmpa_api.h"
#include "types/op_model.h"
#include "types/acl_op.h"
#include "op_model_cache.h"
#include "compile/op_compiler.h"
#include "utils/acl_op_map.h"

namespace acl {
class ACL_FUNC_VISIBILITY OpModelManager {
public:
    ~OpModelManager() = default;

    static OpModelManager &GetInstance()
    {
        static OpModelManager instance;
        return instance;
    }

    aclError LoadAllModels(const std::string &modelDir);

    aclError LoadModelFromMem(const void *const model, const size_t modelSize, const bool isStatic = false);

    aclError LoadModelFromSharedMem(const std::shared_ptr<void> &model, const size_t modelSize, const AclOp *const aclOp,
        const bool isStatic = false);

    aclError GetOpModel(AclOp &aclOp);

    aclError MatchOpModel(const AclOp &aclOp, OpModel &opModel, bool &isDynamic);

    aclError HandleMaxOpQueueConfig(const char_t *const configPath);

    aclError SetHostMemToConst(const AclOp &aclopHostMemToConst, bool &isExistConst) const;

    static aclError SetTensorConst(aclTensorDesc *const desc, const aclDataBuffer *const dataBuffer);

    static void SetCompileFlag(const int32_t flag);

private:
    OpModelManager() = default;

    using ModelMap = AclOpMap<std::shared_ptr<OpModelDef>>;

    aclError RegisterModel(OpModelDef &&modelConfig,
                           ModelMap &opModelDefs,
                           const bool isDynamic,
                           const bool isStaticRegister = true);

    aclError ReadModelDefs(const std::string &configPath,
                            std::vector<OpModelDef> &configList);

    aclError BuildOpModel(const AclOp &aclOp);

    static bool OmFileFilterFn(const std::string &fileName);

    static bool IsDynamicOpModel(const OpModelDef &modelDef);

    static bool IsDynamicOpModel(const AclOp &aclOp);

    aclError MatchStaticOpModel(const AclOp &aclOp, OpModel &opModel, bool &isDynamic, bool &isNeedMatchDymaic);
    aclError MatchDynamicOpModel(const AclOp &aclOp, OpModel &opModel, bool &isDynamic);

private:
    ModelMap opModels_;
    OpModelCache modelCache_;
};
} // namespace acl

#endif // ACL_OP_EXEC_OP_MODEL_MANAGER_H_
